package com.pangu.web.service.impl;

import java.lang.reflect.InvocationTargetException;
import java.util.*;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.pangu.core.BMDataContext;
import com.pangu.core.cache.CacheHelper;
import com.pangu.core.engine.game.ActionTaskUtils;
import com.pangu.web.model.Notice;
import com.pangu.web.model.NoticeMessage;
import com.pangu.web.model.PlayUserClient;
import com.pangu.web.service.NoticeService;
import com.pangu.web.service.repository.jpa.NoticeRepository;
import com.pangu.web.service.repository.jpa.UserQuestionRepository;

/**
 * @author Chris
 * @date 2018/4/9 13:50
 * @todo 通知服务层
 */
@Service
public class NoticeServiceImpl implements NoticeService {

	@Autowired
	private NoticeRepository noticeRepository;

	@Autowired
	private UserQuestionRepository userQuestionRepository;

	@Override
	@Transactional(readOnly = false, rollbackFor = Throwable.class)
	public void saveNotice(Notice notice, HttpServletRequest request) {
		// 保存通知
		noticeRepository.save(notice);
		// 修改问题状态为已回复
		userQuestionRepository.updateStatusById("1", new Date(), notice.getUserquestionid());
	}

	/**
	 * 
	 * Description: 保存并推送公告到前台
	 * 
	 * @author abo
	 * @date 2018年5月12日
	 * @param Notice
	 */
	public void sendNotice(Notice notice) {
		// PlayUserESRepository playersRes = BMDataContext.getContext().getBean(PlayUserESRepository.class);
		// 从缓存里面查询在线人数
//		Page<PlayUser> list = playersRes.findByOrgiAndOnline(BMDataContext.SYSTEM_ORGI, true, new PageRequest(0, 999));
		Collection c = CacheHelper.getApiUserCacheBean().getAllCacheObject(BMDataContext.SYSTEM_ORGI);
		List<PlayUserClient> playUserClients = new ArrayList<PlayUserClient>();
		NoticeMessage noticeMessage = new NoticeMessage();
		try {
			BeanUtils.copyProperties(noticeMessage, notice);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		for(Object userId : c)  {
			PlayUserClient puc = new PlayUserClient();
			puc.setId(userId.toString());
			playUserClients.add(puc);
		}
		// 发送socket请求给前端
		ActionTaskUtils.sendEvent(BMDataContext.BEIMI_PUSHNOTICE_EVENT, noticeMessage, playUserClients);
	}

	/**
	 * 
	 * Description: 首页公告查询接口
	 * 
	 * @author abo
	 * @date 2018年5月12日
	 * @param notice
	 *            查询对象，这里传入的userid
	 * @param sort
	 *            排序对象
	 * @return
	 */
	public List<Notice> getNoticeListByUserId(Notice notice, Sort sort) {
		Specification<Notice> specification = new Specification<Notice>() {
			/*
			 * @param root:代表的查询的实体类
			 * 
			 * @param query：可以从中得到Root对象，即告知JPA Criteria查询要查询哪一个实体类，
			 * 还可以来添加查询条件，还可以结合EntityManager对象得到最终查询的TypedQuery 对象
			 * 
			 * @Param cb:criteriabuildre对象，用于创建Criteria相关的对象工程，当然可以从中获取到predicate类型
			 * 
			 * @return:代表一个查询条件
			 */
			@Override
			public Predicate toPredicate(Root<Notice> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				Predicate p1 = cb.equal(root.get("userid").as(String.class), notice.getUserid());
				Predicate p2 = cb.isNull(root.get("userid").as(String.class));
				// 构建组合的Predicate示例：
				Predicate p = cb.and(cb.or(p1, p2));
				return p;
			}
		};
		List<Notice> page = (List<Notice>) noticeRepository.findAll(specification, sort);
		return page;

	}
}
